package com.peycard.vista;

import java.io.IOException;
import java.io.Serializable;
import java.text.ParseException;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import javax.faces.model.SelectItem;

import org.hibernate.validator.Email;
import org.hibernate.validator.Length;
import org.hibernate.validator.Max;
import org.hibernate.validator.Min;
import org.hibernate.validator.NotEmpty;
import org.hibernate.validator.NotNull;
import org.hibernate.validator.Range;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Controller;

import com.peycard.common.CompanyDTO;
import com.peycard.common.MobileUserDTO;
import com.peycard.service.BaseService;
import com.peycard.util.Constantes;
import com.peycard.util.Utils;

@Controller(Constantes.BEAN_USUARIOS_MOVIL)
@Scope(Constantes.SCOPE_REQUEST)
public class UsuarioMovilControlador extends BaseController implements
		Serializable {
	private static final Logger LOGGER = LoggerFactory
			.getLogger(UsuarioPortalControlador.class);
	private static final long serialVersionUID = 1L;
	private long idCompany;
	private long idMobileUser;
	@NotEmpty
	private String user;
	private String password;
	private String passwordChanged;
	private String repeatPassword;
	private Date dateModifiedPwd;
	@NotEmpty
	@Length(max = 20, message = "El valor es muy grande")
	private String firstName;
	@NotEmpty
	@Length(max = 20)
	private String lastName;
	@NotEmpty
	@Length(max = 50)
	private String address;
	@NotEmpty
	@Length(max = 5)
	private String zipCode;
	private Date dateModified;
	@NotEmpty
	@Length(max = 1)
	private String firstAccess;
	@Email
	private String email;
	@NotEmpty
	@Length(min = 8, max = 10)
	private String phoneNumber;
	@NotEmpty
	@Length(min = 11, max = 20)
	private String mobilephone;
	@NotEmpty
	@Length(max = 20)
	private String country;
	@NotEmpty
	@Length(max = 20)
	private String state;
	private long idEmployee;
	private String rfc;
	private String curp;
	@NotNull
	@Min(18)
	@Max(100)
	private int age;
	@NotEmpty
	private String gender;
	private String currentToken;
	private String username;
	@NotNull
	@Min(0)
	@Max(1)
	private int isActive;
	private String securityQuestion;
	@Length(min = 3, max = 20)
	private String answerQuestion;
	private MobileUserDTO currentItem;
	private List<MobileUserDTO> listItems;
	private List<SelectItem> companyItems;
	private String newTradename;
	@NotEmpty
	private String newUser;
	@NotEmpty
	private String newPassword;
	@NotEmpty
	private String repeatNewPassword;
	@NotEmpty
	@Length(min = 3, max = 20)
	private String newFirstName;
	@NotEmpty
	@Length(min = 3, max = 20)
	private String newLastName;
	@NotEmpty
	@Length(min = 10, max = 50)
	private String newAddress;
	@NotEmpty
	@Length(min = 5, max = 5)
	private String newZipCode;
	@NotEmpty
	@Length(min = 1, max = 1)
	private String newFirstAccess;
	@NotEmpty
	@Email
	private String newEmail;
	@NotEmpty
	@Length(min = 8, max = 10)
	private String newPhoneNumber;
	@NotEmpty
	@Length(min = 11, max = 20)
	private String newMobilephone;
	@NotEmpty
	@Length(min = 5, max = 20)
	private String newCountry;
	@NotEmpty
	@Length(min = 3, max = 20)
	private String newState;
	private long newIdEmployee;
	private String newRfc;
	private String newCurp;
	@NotNull
	@Range(min = 18, max = 70, message = "El valor debe estar entre {min} y {max}")
	private int newAge;
	@NotEmpty
	private String newGender;
	private String newCurrentToken;
	private String newUsername;
	private long newIdCompany;
	@NotNull
	@Min(0)
	@Max(1)
	private int newIsActive;
	@NotEmpty
	private String newSecurityQuestion;
	@NotEmpty
	@Length(min = 3, max = 20)
	private String newAnswerQuestion;

	/**
	 * Constructor sin argumentos, inicializa el valor del token y del usuario
	 * que está actualmente usando el sistema.
	 */
	public UsuarioMovilControlador() {
		companyItems = new ArrayList<SelectItem>();
		currentToken = super.getTokenInContext();
		username = "jamaro";// super.userLogged();
	}

	/**
	 * Método que limpia los objectos
	 */
	private void clearFields() {
		user = "";
		password = "";
		dateModifiedPwd = null;
		firstName = "";
		lastName = "";
		address = "";
		zipCode = "";
		dateModified = null;
		firstAccess = "";
		email = "";
		phoneNumber = "";
		mobilephone = "";
		country = "";
		state = "";
		idEmployee = 0;
		rfc = "";
		curp = "";
		age = 0;
		gender = "";
		username = "";
		isActive = 0;
		securityQuestion = "";
		answerQuestion = "";
	}

	/**
	 * Envía y en base a la respuesta contruye una lista de usuarios, la cual se
	 * mostrará en la pantalla de usuarios de aplicación móvil en cuanto acceda
	 * a ella.
	 */
	// TODO:Crear peticion de lista de compañias
	private void init() {
		try {
			BaseService service = new BaseService();
			service.setToken(currentToken);
			service.listISOMessage(Constantes.ISO003_MOBILE_APP_USER_LIST,
					Constantes.MOBILE_USERNAME, username,
					Constantes.MOBILE_USER_LIST_KEY);
			List<String> userList = service.getList();
			if (userList != null) {
				listItems = new ArrayList<MobileUserDTO>();
				for (int i = 0; i < userList.size(); i++) {
					String currentUser = userList.get(i);
					List<String> userData = Utils.convertList(currentUser);
					MobileUserDTO dto = new MobileUserDTO();
					dto.setIdMobileUser(new Long(userData.get(0)));
					dto.setUser(userData.get(1));
					dto.setPassword(userData.get(2));
					// dto.setDateModifiedPwd(new Date(userData.get(x));
					dto.setFirstName(userData.get(4));
					dto.setLastName(userData.get(5));
					dto.setAddress(userData.get(6));
					// dto.setDateModified(new Date(userData.get(x));
					dto.setZipCode(userData.get(7));
					dto.setEmail(userData.get(9));
					dto.setPhoneNumber(userData.get(10));
					dto.setMobilephone(userData.get(11));
					dto.setCountry(userData.get(12));
					dto.setState(userData.get(13));
					dto.setIdEmployee(new Long(userData.get(14)));
					dto.setRfc(userData.get(15));
					dto.setCurp(userData.get(16));
					dto.setAge(Integer.valueOf(userData.get(17)));
					dto.setGender(userData.get(18));
					dto.setSecurityQuestion(userData.get(19));
					dto.setAnswerQuestion(userData.get(20));
					listItems.add(dto);
				}
				super.setTokenInContext(service.getToken());
			} else {
				super.addErrorMessage(service.getMessage());
			}
			// clearFields();
		} catch (IOException e) {
			super.addErrorMessage("No fue posible conectarse con el servidor.");
		} catch (ParseException e) {
			super.addWarningMessage("Ocurrió un error al parsear la petición.");
		}
	}

	public String createUser() {
		if (newPassword != null && repeatNewPassword != null) {
			if (newPassword.equals(repeatNewPassword)) {
				newUsername = "jamaro";
				newIsActive = 0;
				String encodedPwd = Utils.encryptPassword(newPassword);
				String encodedAnswer = Utils.encryptPassword(newAnswerQuestion);
				List<Object> mobileUserData = new ArrayList<Object>();
				mobileUserData.add(newUser);
				mobileUserData.add(encodedPwd);
				mobileUserData.add(newFirstName);
				mobileUserData.add(newLastName);
				mobileUserData.add(newAddress);
				mobileUserData.add(newZipCode);
				mobileUserData.add(newFirstAccess);
				mobileUserData.add(newEmail);
				mobileUserData.add(newPhoneNumber);
				mobileUserData.add(newMobilephone);
				mobileUserData.add(newCountry);
				mobileUserData.add(newState);
				mobileUserData.add(newRfc);
				mobileUserData.add(newCurp);
				mobileUserData.add(newAge);
				mobileUserData.add(newGender);
				mobileUserData.add(newUsername);
				mobileUserData.add(newIsActive);
				mobileUserData.add(newSecurityQuestion);
				mobileUserData.add(encodedAnswer);
				LOGGER.info("**" + mobileUserData.toString() + "***");
				createUpdatePortalUserRequest(
						Constantes.ISO003_NEW_MOBILE_APP_USER, mobileUserData);
			} else {
				super.addInfoMessage("Las contraseñas no coinciden");
			}
		} else {
			super.addInfoMessage("La contraseña no puede estar vacía");
		}
		return "";
	}

	public String updateUser() {
		String encodedAnswer = currentItem.getAnswerQuestion();
		String encodedPwd = currentItem.getPassword();

		if (!password.equals(currentItem.getPassword())) {
			encodedPwd = Utils.encryptPassword(password);
		}

		if (!answerQuestion.equals(currentItem.getAnswerQuestion())) {
			encodedAnswer = Utils.encryptPassword(answerQuestion);
		}

		List<Object> mobileUserData = new ArrayList<Object>();
		mobileUserData.add(user);
		mobileUserData.add(encodedPwd);
		mobileUserData.add(firstName);
		mobileUserData.add(lastName);
		mobileUserData.add(address);
		mobileUserData.add(zipCode);
		mobileUserData.add(firstAccess);
		mobileUserData.add(email);
		mobileUserData.add(phoneNumber);
		mobileUserData.add(mobilephone);
		mobileUserData.add(country);
		mobileUserData.add(state);
		mobileUserData.add(rfc);
		mobileUserData.add(curp);
		mobileUserData.add(age);
		mobileUserData.add(gender);
		mobileUserData.add(username);
		mobileUserData.add(isActive);
		mobileUserData.add(securityQuestion);
		mobileUserData.add(encodedAnswer);
		mobileUserData.add(idCompany);
		createUpdatePortalUserRequest(Constantes.ISO003_UPDATE_MOBILE_APP_USER,
				mobileUserData);
		return "";
	}

	public String deleteUser() {
		List<Object> deleteMobileUserData = new ArrayList<Object>();
		long idMobileUser = currentItem.getIdMobileUser();
		deleteMobileUserData.add(idMobileUser);
		deleteMobileUserData.add(username);
		String deleteString = Utils.buildStringData(deleteMobileUserData);
		try {
			BaseService service = new BaseService();
			service.setToken(currentToken);
			boolean response = service.isoMessageRequest(
					Constantes.ISO003_DELETE_PORTAL_USER,
					Constantes.DELETE_PORTAL_USER_METADATA, deleteString);
			if (response) {
				super.setTokenInContext(service.getToken());
			} else {
				super.addErrorMessage(service.getMessage());
			}
		} catch (IOException e) {
			super.addErrorMessage("No fue posible conectarse con el servidor.");
		} catch (ParseException e) {
			super.addWarningMessage("Ocurrió un error al parsear la petición.");
		}
		return "";
	}

	public void createUpdatePortalUserRequest(String proccessingCode,
			List<Object> mobileUserData) {

		String metadata = Constantes.CREATE_UPDATE_MOBILE_USER_METADATA;
		String string = Utils.buildStringData(mobileUserData);
		try {
			BaseService service = new BaseService();
			service.setToken(currentToken);
			boolean response = service.isoMessageRequest(proccessingCode,
					metadata, string);
			if (response) {
				super.setTokenInContext(service.getToken());
			} else {
				super.addErrorMessage(service.getMessage());
			}
		} catch (IOException e) {
			super.addErrorMessage("No fue posible conectarse con el servidor.");
		} catch (ParseException e) {
			super.addWarningMessage("Ocurrió un error al parsear la petición.");
		}
	}

	public String companies() {
		List<CompanyDTO> list = companyList();
		companyItems = new ArrayList<SelectItem>();
		if (list.size() > 0) {
			for (int i = 0; i < list.size(); i++) {
				String currentTradename = list.get(i).getTradename();
				SelectItem selectTradename = new SelectItem(currentTradename);
				companyItems.add(selectTradename);
			}
		} else {
			super.addWarningMessage("No hay marcas disponibles.");
		}
		return "";
	}

	private List<CompanyDTO> companyList() {
		List<CompanyDTO> list = new ArrayList<CompanyDTO>();
		try {
			BaseService service = new BaseService();
			service.setToken(currentToken);
			service.listISOMessage(Constantes.ISO003_COMPANY_LIST,
					Constantes.COMPANY_USERNAME, username,
					Constantes.COMPANY_LIST_KEY);
			List<String> companyList = service.getList();
			LOGGER.info("[**" + companyList + "**]");
			if (companyList != null) {
				for (int i = 0; i < companyList.size(); i++) {
					String currentCompany = companyList.get(i);
					List<String> companyData = Utils
							.convertList(currentCompany);
					CompanyDTO dto = new CompanyDTO();
					long id = Long.valueOf(companyData.get(0));
					dto.setIdCompany(id);
					dto.setTradename(companyData.get(1));
					dto.setSocialReason(companyData.get(2));
					dto.setCorporateSpin(companyData.get(3));
					dto.setRfc(companyData.get(4));
					dto.setInfonavit(companyData.get(5));
					dto.setLegalRepresentative(companyData.get(6));
					dto.setStps(companyData.get(7));
					dto.setStpsRepresentative(companyData.get(8));
					dto.setCountry(companyData.get(9));
					dto.setState(companyData.get(10));
					dto.setStreet(companyData.get(11));
					dto.setNumberInEx(companyData.get(12));
					dto.setSuburb(companyData.get(13));
					dto.setZipCode(companyData.get(14));
					dto.setTelephone1(companyData.get(15));
					dto.setTelephone2(companyData.get(16));
					dto.setFax(companyData.get(17));
					dto.setEmail(companyData.get(18));
					dto.setWeb(companyData.get(19));
					dto.setIsActive(Short.valueOf(companyData.get(20)));
					list.add(dto);
				}
				super.setTokenInContext(service.getToken());
			} else {
				super.addErrorMessage(service.getMessage());
			}
		} catch (IOException e) {
			super.addErrorMessage("No fue posible conectarse con el servidor.");
		} catch (ParseException e) {
			super.addWarningMessage("Ocurrió un error al parsear la petición.");
		}
		return list;
	}

	public void setValues(MobileUserDTO dto) {
		clearFields();
		user = dto.getUser();
		password = dto.getPassword();
		firstName = dto.getFirstName();
		lastName = dto.getLastName();
		address = dto.getAddress();
		zipCode = dto.getZipCode();
		firstAccess = dto.getFirstAccess();
		email = dto.getEmail();
		phoneNumber = dto.getPhoneNumber();
		mobilephone = dto.getMobilephone();
		country = dto.getCountry();
		state = dto.getState();
		idEmployee = dto.getIdEmployee();
		rfc = dto.getRfc();
		curp = dto.getCurp();
		age = dto.getAge();
		gender = dto.getGender();
		isActive = dto.getIsActive();
		securityQuestion = dto.getSecurityQuestion();
		answerQuestion = dto.getAnswerQuestion();
	}

	public MobileUserDTO getCurrentItem() {
		return currentItem;
	}

	public void setCurrentItem(MobileUserDTO currentItem) {
		setValues(currentItem);
		this.currentItem = currentItem;
	}

	public List<MobileUserDTO> getListItems() {
		init();
		return listItems;
	}

	public void setListItems(List<MobileUserDTO> listItems) {
		this.listItems = listItems;
	}

	public long getIdMobileUser() {
		return idMobileUser;
	}

	public void setIdMobileUser(long idMobileUser) {
		this.idMobileUser = idMobileUser;
	}

	public String getUser() {
		return user;
	}

	public void setUser(String user) {
		this.user = user;
	}

	public String getPassword() {
		return password;
	}

	public void setPassword(String password) {
		this.password = password;
	}

	public String getPasswordChanged() {
		return passwordChanged;
	}

	public void setPasswordChanged(String passwordChanged) {
		this.passwordChanged = passwordChanged;
	}

	public String getRepeatPassword() {
		return repeatPassword;
	}

	public void setRepeatPassword(String repeatPassword) {
		this.repeatPassword = repeatPassword;
	}

	public Date getDateModifiedPwd() {
		return dateModifiedPwd;
	}

	public void setDateModifiedPwd(Date dateModifiedPwd) {
		this.dateModifiedPwd = dateModifiedPwd;
	}

	public String getFirstName() {
		return firstName;
	}

	public void setFirstName(String firstName) {
		this.firstName = firstName;
	}

	public String getLastName() {
		return lastName;
	}

	public void setLastName(String lastName) {
		this.lastName = lastName;
	}

	public String getAddress() {
		return address;
	}

	public void setAddress(String address) {
		this.address = address;
	}

	public String getZipCode() {
		return zipCode;
	}

	public void setZipCode(String zipCode) {
		this.zipCode = zipCode;
	}

	public Date getDateModified() {
		return dateModified;
	}

	public void setDateModified(Date dateModified) {
		this.dateModified = dateModified;
	}

	public String getFirstAccess() {
		return firstAccess;
	}

	public void setFirstAccess(String firstAccess) {
		this.firstAccess = firstAccess;
	}

	public String getEmail() {
		return email;
	}

	public void setEmail(String email) {
		this.email = email;
	}

	public String getPhoneNumber() {
		return phoneNumber;
	}

	public void setPhoneNumber(String phoneNumber) {
		this.phoneNumber = phoneNumber;
	}

	public String getMobilephone() {
		return mobilephone;
	}

	public void setMobilephone(String mobilephone) {
		this.mobilephone = mobilephone;
	}

	public String getCountry() {
		return country;
	}

	public void setCountry(String country) {
		this.country = country;
	}

	public String getState() {
		return state;
	}

	public void setState(String state) {
		this.state = state;
	}

	public long getIdEmployee() {
		return idEmployee;
	}

	public void setIdEmployee(long idEmployee) {
		this.idEmployee = idEmployee;
	}

	public String getRfc() {
		return rfc;
	}

	public void setRfc(String rfc) {
		this.rfc = rfc;
	}

	public String getCurp() {
		return curp;
	}

	public void setCurp(String curp) {
		this.curp = curp;
	}

	public int getAge() {
		return age;
	}

	public void setAge(int age) {
		this.age = age;
	}

	public String getGender() {
		return gender;
	}

	public void setGender(String gender) {
		this.gender = gender;
	}

	public String getCurrentToken() {
		return currentToken;
	}

	public void setCurrentToken(String currentToken) {
		this.currentToken = currentToken;
	}

	public String getUsername() {
		return username;
	}

	public void setUsername(String username) {
		this.username = username;
	}

	public int getIsActive() {
		return isActive;
	}

	public void setIsActive(int isActive) {
		this.isActive = isActive;
	}

	public String getSecurityQuestion() {
		return securityQuestion;
	}

	public void setSecurityQuestion(String securityQuestion) {
		this.securityQuestion = securityQuestion;
	}

	public String getAnswerQuestion() {
		return answerQuestion;
	}

	public void setAnswerQuestion(String answerQuestion) {
		this.answerQuestion = answerQuestion;
	}

	public String getNewUser() {
		return newUser;
	}

	public void setNewUser(String newUser) {
		this.newUser = newUser;
	}

	public String getNewPassword() {
		return newPassword;
	}

	public void setNewPassword(String newPassword) {
		this.newPassword = newPassword;
	}

	public String getRepeatNewPassword() {
		return repeatNewPassword;
	}

	public void setRepeatNewPassword(String repeatNewPassword) {
		this.repeatNewPassword = repeatNewPassword;
	}

	public String getNewFirstName() {
		return newFirstName;
	}

	public void setNewFirstName(String newFirstName) {
		this.newFirstName = newFirstName;
	}

	public String getNewLastName() {
		return newLastName;
	}

	public void setNewLastName(String newLastName) {
		this.newLastName = newLastName;
	}

	public String getNewAddress() {
		return newAddress;
	}

	public void setNewAddress(String newAddress) {
		this.newAddress = newAddress;
	}

	public String getNewZipCode() {
		return newZipCode;
	}

	public void setNewZipCode(String newZipCode) {
		this.newZipCode = newZipCode;
	}

	public String getNewFirstAccess() {
		return newFirstAccess;
	}

	public void setNewFirstAccess(String newFirstAccess) {
		this.newFirstAccess = newFirstAccess;
	}

	public String getNewEmail() {
		return newEmail;
	}

	public void setNewEmail(String newEmail) {
		this.newEmail = newEmail;
	}

	public String getNewPhoneNumber() {
		return newPhoneNumber;
	}

	public void setNewPhoneNumber(String newPhoneNumber) {
		this.newPhoneNumber = newPhoneNumber;
	}

	public String getNewMobilephone() {
		return newMobilephone;
	}

	public void setNewMobilephone(String newMobilephone) {
		this.newMobilephone = newMobilephone;
	}

	public String getNewCountry() {
		return newCountry;
	}

	public void setNewCountry(String newCountry) {
		this.newCountry = newCountry;
	}

	public String getNewState() {
		return newState;
	}

	public void setNewState(String newState) {
		this.newState = newState;
	}

	public long getNewIdEmployee() {
		return newIdEmployee;
	}

	public void setNewIdEmployee(long newIdEmployee) {
		this.newIdEmployee = newIdEmployee;
	}

	public String getNewRfc() {
		return newRfc;
	}

	public void setNewRfc(String newRfc) {
		this.newRfc = newRfc;
	}

	public String getNewCurp() {
		return newCurp;
	}

	public void setNewCurp(String newCurp) {
		this.newCurp = newCurp;
	}

	public int getNewAge() {
		return newAge;
	}

	public void setNewAge(int newAge) {
		this.newAge = newAge;
	}

	public String getNewGender() {
		return newGender;
	}

	public void setNewGender(String newGender) {
		this.newGender = newGender;
	}

	public String getNewCurrentToken() {
		return newCurrentToken;
	}

	public void setNewCurrentToken(String newCurrentToken) {
		this.newCurrentToken = newCurrentToken;
	}

	public String getNewUsername() {
		return newUsername;
	}

	public void setNewUsername(String newUsername) {
		this.newUsername = newUsername;
	}

	public int getNewIsActive() {
		return newIsActive;
	}

	public void setNewIsActive(int newIsActive) {
		this.newIsActive = newIsActive;
	}

	public String getNewSecurityQuestion() {
		return newSecurityQuestion;
	}

	public void setNewSecurityQuestion(String newSecurityQuestion) {
		this.newSecurityQuestion = newSecurityQuestion;
	}

	public String getNewAnswerQuestion() {
		return newAnswerQuestion;
	}

	public void setNewAnswerQuestion(String newAnswerQuestion) {
		this.newAnswerQuestion = newAnswerQuestion;
	}

	public long getIdCompany() {
		return idCompany;
	}

	public void setIdCompany(long idCompany) {
		this.idCompany = idCompany;
	}

	public List<SelectItem> getCompanyItems() {
		return companyItems;
	}

	public void setCompanyItems(List<SelectItem> companyItems) {
		this.companyItems = companyItems;
	}

	public long getNewIdCompany() {
		return newIdCompany;
	}

	public void setNewIdCompany(long newIdCompany) {
		this.newIdCompany = newIdCompany;
	}

	public String getNewTradename() {
		return newTradename;
	}

	public void setNewTradename(String newTradename) {
		this.newTradename = newTradename;
	}

}
